<template>
  <div class="aes">
    <div v-show="visible" id="51-container" style="display: none"></div>
    <div v-show="beginBtnVisible" class="begin">
      <button type="button" class="cloud-btn" @click="handleBtnClick">{{ btnText }}</button>
    </div>
  </div>
</template>

<script setup>
  import {ref, toRaw, computed, watch, defineProps, onMounted, onUnmounted} from 'vue'
  import {useStore} from 'vuex'
  import axios from 'axios'

  defineProps({
    visible: {
      type: Boolean,
      default: false,
    },
  })

  const cloudRender = new cloudRenderer('51-container', 0)
  let btnText = ref('Start Now')

  const store = useStore()
  const layoutInfo = computed(() => {
    const res = store.getters['layout/info']
    res.countList = toRaw(res.countList)
    return res
  })
  watch(layoutInfo, (newVal, oldVal) => {
    const {menu, tag, countList} = newVal
    const {menu: oldMenu, tag: oldTag, countList: oldCountList} = oldVal
    if (JSON.stringify(menu) != JSON.stringify(oldMenu) || JSON.stringify(tag) != JSON.stringify(oldTag)) {
      // 重新加载数据
      changeCoveringData()
    } else {
      // 调整3D内容显示
      const add = countList.concat(oldCountList).filter(val => !oldCountList.includes(val))
      const reduce = countList.concat(oldCountList).filter(val => !countList.includes(val))
      if (add.length > 0) {
        changeCoveringShow(add, true)
      }
      if (reduce.length > 0) {
        changeCoveringShow(reduce, false)
      }
    }
  })
  function changeCoveringShow(difference, isShow) {
    difference.forEach(item => {
      if (item == '管网') {
        changeCoveringVisible(
          pipeData.map(item => item.id),
          'path',
          isShow
        )
      }
      if (item == '监测点') {
        changeCoveringVisible(
          pointData.map(item => item.id),
          'poi',
          isShow
        )
      }
      if (item == '扩散污染') {
        changeCoveringVisible(
          heatmapData.map(item => item.id),
          'heatmap',
          isShow
        )
      }
      if (item == '水位图') {
        changeCoveringVisible(
          heatmapData.map(item => item.id),
          'heatmap',
          isShow
        )
      }
      if (item == '降雨分布') {
        changeCoveringVisible(
          columnheatData.map(item => item.id),
          'columnar_heatmap',
          isShow
        )
      }
      const iconName =
        item == '水源'
          ? 'icon_sy'
          : item == '水厂'
          ? 'icon_shuic'
          : item == '泵站'
          ? 'icon_beng'
          : item == '水质监测'
          ? 'icon_sz'
          : item == '水位监测'
          ? 'icon_sw'
          : item == '大表'
          ? 'icon_db'
          : item == '污水厂'
          ? 'icon_wsc'
          : item == '事件信息'
          ? 'icon_danger'
          : false
      if (iconName) {
        const idList = pointData
          .filter(item => item.marker.images[0].normal_url.search(iconName) != -1)
          .map(item => item.id)
        changeCoveringVisible(idList, 'poi', isShow)
      }
    })
  }
  function changeCoveringData() {
    if (isReady) {
      const {menu, tag} = layoutInfo.value
      switch (menu) {
        case '智慧供水':
          switch (tag) {
            case '概览':
              getCoveringData('/json/controller.json').finally(() => {
                flyByCoord('113.330917,23.115299')
              })
              break
            case 'DMA':
              getCoveringData('/json/dma.json').finally(() => {
                if (rangeData.length > 0 && rangeData[Math.floor(rangeData.length / 2)].points.length > 0) {
                  flyByCoord(rangeData[Math.floor(rangeData.length / 2)].points[0].coord, 3000, 45, 340)
                }
              })
              break
            case '扩散污染':
              getCoveringData('/json/pollute.json').finally(() => {
                if (pathData.length > 0 && pathData[0].points.length > 0) {
                  flyByCoord(pathData[0].points[Math.floor(pathData[0].points.length / 2)].coord, 2000, 35, 75)
                }
              })
              break
            case '资产管理':
              getCoveringData('/json/property.json').finally(() => {
                flyByCoord('113.330917,23.115299')
              })
              break
            case '远传水表':
              cleanData()
              break
          }
          break
        case '智慧排水':
          getCoveringData('/json/drain.json').finally(() => {
            if (pipeData.length > 0 && pipeData[0].points.length > 0) {
              flyByCoord('113.330917,23.115299')
            }
          })
          break
        case '智慧内河':
          switch (tag) {
            case '水质监测':
              getCoveringData('/json/waterQuality.json').finally(() => {
                changeCoveringShow(['扩散污染'], false)
                flyByCoord('113.334084,23.112036', 1500, 35, 45)
              })
              break
            case '水位监测':
              getCoveringData('/json/waterLine.json').finally(() => {
                changeCoveringShow(['水位图', '降雨分布'], false)
                flyByCoord('113.334084,23.112036')
              })
              break
            case '无人机巡查':
              getCoveringData('/json/patrol.json').finally(() => {
                if (pathData.length > 0 && pathData[0].points.length > 0) {
                  flyByCoord('113.318817,23.114037', 1500, 35, 45)
                }
              })
              break
          }
          break
        default:
          break
      }
    }
  }

  let isReady = false
  let beginBtnVisible = true
  function handleBtnClick() {
    btnText.value = 'Loading ...'
    GetUrlStartRenderCloud()
  }

  // onMounted(() => {
  //   setTimeout(GetUrlStartRenderCloud(), 5000)
  // })
  function GetUrlStartRenderCloud() {
    const cloudurl = 'http://192.168.2.192:8889' //云渲染服务地址 (Cloud rendering service address) ①本地IP: http://172.31.9.21:8889, ②域名: https://vizservice.51hitech.com
    const orderID = '6BA801d6' //渲染口令, 在云渲染客户端上获得 (Project ID, obtained on the cloud rendering client)
    fetch(`${cloudurl}/Renderers/Any/order`, {
      //方式 ①
      method: 'POST',
      headers: {
        'Content-type': 'application/x-www-form-urlencoded',
      },
      body: `order=${orderID}&width=${window.innerWidth}&height=${window.innerHeight}`,
      //初始化云渲染固定分辨率输出, 可选, 默认以云渲染客户端设置的分辨率输出
      // Initialize cloud rendering output at fixed resolution, optional, default output is at the resolution set by the cloud rendering client

      //方式 ②
      //method: "POST",
      //headers: { "Content-type": "application/json" },
      //body: JSON.stringify({order:order, width:window.innerWidth, height:window.innerHeight})
    })
      .then(res => res.json())
      .then(json => {
        if (json.success && json.url) {
          //启动云渲染 (Start cloud rendering)
          cloudRender.SuperAPI('StartRenderCloud', json.url)

          //事件注册 (Callbakc event registration)
          cloudRender.SuperAPI('RegisterCloudResponse', myHandleResponseFunction)
        } else {
          btnText.value = 'Start Now'
          alert(json.message)
        }
      })
      .catch(error => {
        console.error('Error:', error)
      })
  }
  // 事件注册函数 (Event handler function)
  function myHandleResponseFunction(data) {
    let jsonObject = JSON.parse(data)
    console.log('FuncName: ', jsonObject.func_name)
    switch (jsonObject.func_name) {
      case 'beginPlay':
        beginBtnVisible = false
        break

      case 'APIAlready':
        console.log('APIAlready: 3D世界加载完成')
        isReady = true
        //云渲染场景加载完成 业务逻辑...
        //Do something when 3D world loading is complete
        // openCoordTool(true)
        // openMeasureTool(true)
        getCoveringData('/json/controller.json').finally(() => {
          flyByCoord('113.330917,23.115299')
        })
        break

      case 'OnPOIClick':
        // console.log('OnPOIClick_id = ' + jsonObject.args.id)
        // 返回一个点击POI的ID值
        // Do something when return the ID of a clicked POI
        cloudRender.SuperAPI('FocusPOI', {id: jsonObject.args.id, distance: 1000})
        break
      case 'OnRangeClick':
        // 返回一个点击Range的ID值
        // Do something when return the ID of a clicked POI
        cloudRender.SuperAPI('FocusRange', {id: jsonObject.args.id, distance: 2000})
        store.commit('layout/SET_IS_DETAIL', true)
        break
    }
    return data
  }

  // 打开/关闭测量工具
  function openMeasureTool(type) {
    if (type) {
      cloudRender.SuperAPI(
        'StartMeasureTool',
        {
          coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
          cad_mapkey: '', //CAD基准点Key值, 项目中约定
        },
        e => {
          console.log(e)
        }
      )
    } else {
      cloudRender.SuperAPI('EndMeasureTool')
    }
  }

  // 打开/关闭取点工具
  function openCoordTool(type) {
    if (type) {
      cloudRender.SuperAPI(
        'StartGetCoord',
        {
          coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
          cad_mapkey: '', //CAD基准点Key值, 项目中约定
          coord_z_type: 0, //坐标高度类型(0:相对3D世界表面；1:相对3D世界地面；2:相对3D世界海拔; 注:cad坐标无效)
        },
        e => {
          const res = JSON.parse(e).coord_result.map(item => {
            return {coord: item.coord}
          })
          console.log(res)
        }
      )
    } else {
      cloudRender.SuperAPI('EndGetCoord')
    }
  }

  let pointData = []
  let rangeData = []
  let pathData = []
  let pipeData = []
  let heatmapData = []
  let columnheatData = []
  // 清空原有数据
  function cleanData() {
    pointData = []
    rangeData = []
    pathData = []
    pipeData = []
    heatmapData = []
    columnheatData = []
    cloudRender.SuperAPI('RemoveAllPOI')
    cloudRender.SuperAPI('RemoveAllRange')
    cloudRender.SuperAPI('RemoveAllPath')
    cloudRender.SuperAPI('RemoveAllHeatMap')
    cloudRender.SuperAPI('RemoveAllColumnHeatMap')
  }
  function getCoveringData(url) {
    // 先清空原有数据
    cleanData()
    return axios.get(url).then(({data}) => {
      const {point, range, path, pipe, heatmap, columnheat} = data
      // 添加自定义POI点
      if (point) {
        point.forEach((item, index) => {
          const data = {
            id: item.id || `point_${index}`,
            coord_type: '0',
            cad_mapkey: '',
            coord: item.coord,
            coord_z: '0',
            coord_z_type: 0,
            always_show_label: false,
            show_label_range: '0,2000',
            sort_order: true,
            state: 'state_1',
            marker: {
              size: item.size,
              images: [
                {
                  define_state: 'state_1',
                  normal_url: location.origin + item.normal_url,
                  activate_url: location.origin + item.activate_url,
                },
              ],
            },
            label: null,
            // label: {
            //   bg_image_url: 'http://superapi.51hitech.com/doc-static/images/static/LabelBg.png',
            //   bg_size: '200,80',
            //   bg_offset: '50,200',
            //   content: [
            //     {
            //       text: ['文本内容A', 'ff0000ff', '30'],
            //       text_offset: '10,5',
            //     },
            //     {
            //       text: ['文本内容B', '00ff00ff', '20'],
            //       text_offset: '10,45',
            //     },
            //   ],
            // },
            window: {
              url: location.origin + '/info',
              size: '500,350',
              offset: '50,180',
            },
          }
          pointData.push(data)
          cloudRender.SuperAPI('AddCustomPOI', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
      // 添加自定义区域
      if (range) {
        range.forEach((item, index) => {
          const data = {
            id: item.id || `range_${index}`,
            coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
            cad_mapkey: '', //CAD基准点Key值, 项目中约定
            coord_z: 0, //高度(单位:米)
            coord_z_type: 0, //坐标高度类型(0:相对3D世界表面；1:相对3D世界地面；2:相对3D世界海拔; 注:cad坐标无效)
            color: item.color, //轮廓颜色(HEX颜色值)
            range_height: item.height, //围栏高度(单位:米)
            stroke_weight: 200, //底部轮廓线宽度(单位:米; 注: 区域中含有内环"inner_points"时无效)
            type: 'box_wave_line', //样式类型; 注①
            fill_area: 'none', //底部区域填充类型; 注②
            points: item.points,
            inner_points: item.points,
          }
          rangeData.push(data)
          cloudRender.SuperAPI('AddRange', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
      // 添加自定义路径
      if (path) {
        path.forEach((item, index) => {
          const data = {
            id: item.id || `path_${index}`,
            coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
            coord_z_type: 0, //坐标高度类型(0:相对3D世界表面；1:相对3D世界地面；2:相对3D世界海拔; 注:cad坐标无效)
            cad_mapkey: '', //CAD基准点Key值, 项目中约定
            type: item.type, //样式类型; 注①
            color: item.color, //颜色(HEX颜色值, "color":"" 透明路径)
            pass_color: item.pass_color, //覆盖物移动经过路径颜色(HEX颜色值)
            width: item.width, //宽度(单位:米)
            points: item.points,
          }
          pathData.push(data)
          cloudRender.SuperAPI('AddPath', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
      if (pipe) {
        pipe.forEach((item, index) => {
          const data = {
            id: item.id || `pipe_${index}`,
            coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
            coord_z_type: 0, //坐标高度类型(0:相对3D世界表面；1:相对3D世界地面；2:相对3D世界海拔; 注:cad坐标无效)
            cad_mapkey: '', //CAD基准点Key值, 项目中约定
            type: item.type, //样式类型; 注①
            color: item.color, //颜色(HEX颜色值, "color":"" 透明路径)
            pass_color: item.pass_color, //覆盖物移动经过路径颜色(HEX颜色值)
            width: item.width, //宽度(单位:米)
            points: item.points,
          }
          pipeData.push(data)
          cloudRender.SuperAPI('AddPath', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
      // 自定义区域热力图
      if (heatmap) {
        heatmap.forEach((item, index) => {
          const data = {
            id: item.id || `heatmap_${index}`,
            coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
            cad_mapkey: '', //CAD基准点Key值, 项目中约定
            coord_z: 10, //高度(单位:米)
            coord_z_type: 0, //坐标高度类型(0:相对3D世界表面; 1:相对3D世界地面; 2:相对3D世界海拔; 注:cad坐标无效)
            heatmap_type: 1, //样式类型(1: 投影型, 贴合地面;  2:平面型)
            leftupper_coord: item.leftupper_coord, //热力区域坐标(左上坐标 lng,lat)
            leftlower_coord: item.leftlower_coord, //热力区域坐标(左下坐标 lng,lat)
            rightlower_coord: item.rightlower_coord, //热力区域坐标(右下坐标 lng,lat)
            rightupper_coord: item.rightupper_coord, //热力区域坐标(右上坐标 lng,lat)
            brush_diameter: 1500, //热力点笔刷直径(单位:米, 单个热力点覆盖直径)
            heatpoint_minvalue: 1, //热力点热力值范围最小值(1:绿色接近透明, 100:最红, 线性计算)
            heatpoint_maxvalue: 100, //热力点热力值范围最大值
            data: item.data,
          }
          heatmapData.push(data)
          cloudRender.SuperAPI('AddHeatMap', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
      if (columnheat) {
        columnheat.forEach((item, index) => {
          const data = {
            id: item.id || `columnheat_${index}`,
            coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
            cad_mapkey: '', //CAD基准点Key值, 项目中约定
            columnar_type: 'cube', //柱状热力图柱体外观类型; cube方柱, cylinder圆柱
            leftupper_coord: item.leftupper_coord, //热力区域坐标(左上坐标 lng,lat)
            leftlower_coord: item.leftlower_coord, //热力区域坐标(左下坐标 lng,lat)
            rightlower_coord: item.rightlower_coord, //热力区域坐标(右下坐标 lng,lat)
            rightupper_coord: item.rightupper_coord, //热力区域坐标(右上坐标 lng,lat)
            coord_z: -10, //高度(单位:米)
            coord_z_type: 1, //坐标高度类型(0:相对3D世界表面；1:相对3D世界地面；2:相对3D世界海拔; 注:cad坐标无效)
            brush_diameter: 120, //热力点笔刷直径(单位:米, 单个热力点覆盖直径)
            heatpoint_minvalue: 1, //热力点热力值范围最小值(1:绿色接近透明, 100:最红, 线性计算)
            heatpoint_maxvalue: 100, //热力点热力值范围最大值
            columnar_width: 100, //(单位:米), 柱状热力图单体宽度(此宽度同时受整个热力图范围大小影响; (数值必需为>=1整型)
            //柱状热力图最多500x500个柱子,如果热力图整体范围长度,宽度/单体柱子宽度 <= 500,则采用单体柱子宽度;
            //否则单体柱子宽度会自动反算一个合适的值)
            columnar_min_height: 1, //单体柱表达最小值的实际高度(单位:米)
            columnar_max_height: 700, //单体柱表达最大值的实际高度(单位:米)
            enable_gap: false, //true 开启柱间隙; false 柱子之间紧贴无间隙
            data: item.data,
          }
          columnheatData.push(data)
          cloudRender.SuperAPI('AddColumnHeatMap', data, status => {
            console.log(status) //成功、失败回调
          })
        })
      }
    })
  }
  // 覆盖物显示隐藏
  function changeCoveringVisible(idList, type, show = true) {
    idList.forEach(id => {
      const jsondata = {
        id: id, //覆盖物id
        covering_type: type, //覆盖物类型, 详见下表
        bshow: show, //true:显示; false:隐藏
      }
      cloudRender.SuperAPI('ShowHideCovering', jsondata, status => {
        console.log(status) //成功、失败回调
      })
    })
  }

  // 聚焦id跳转
  function flyById(id, type, height = 2000) {
    cloudRender.SuperAPI(
      'FocusCovering',
      {
        id: id,
        covering_type: type,
        distance: height,
      },
      status => {
        console.log(status) //成功、失败回调
      }
    )
  }
  // 坐标跳转
  function flyByCoord(coord, height = 2500, pitch = 35, yaw = 135) {
    cloudRender.SuperAPI(
      'SetCameraInfo',
      {
        coord_type: 0, //坐标类型(0:经纬度坐标, 1:cad坐标)
        cad_mapkey: '', //CAD基准点Key值, 项目中约定
        center_coord: coord, //中心点的坐标 lng,lat
        arm_distance: height, //镜头距中心点距离(单位:米)
        pitch: pitch, //镜头俯仰角(5~89)
        yaw: yaw, //镜头偏航角(0正北, 0~359)
        fly: false, //true: 飞行动画(飞行时间根据当前点与目标点计算,则pitch及yaw不生效, 会自行计算);                                                   //false: 立刻跳转过去(有一个短暂飞行动画,并按照arm_distance, pitch, yaw设置镜头)
      },
      status => {
        console.log(status) //成功、失败回调
      }
    )
  }

  // 获取场景镜头信息
  // Get the current camera infomation
  function GetCameraInfo() {
    let jsonData = {
      coord_type: 0,
      cad_mapkey: '',
    }
    cloudRender.SuperAPI('GetCameraInfo', jsonData, e => {
      let data = JSON.parse(e)
      console.log(JSON.stringify(data, null, 2))
    })
  }
  // 关闭场景
  // top cloud rendering service
  function StopRenderCloud() {
    cloudRender.SuperAPI('StopRenderCloud')
    setTimeout(() => window.location.reload(), 3e2)
  }

  // onUnmounted(() => {
  //   StopRenderCloud() //关闭云渲染, 释放资源 (此处是关键。单页应用释放资源请注意)
  // })
</script>

<style scoped>
  .aes {
    background: #000;
    overflow: hidden;
  }
  .cloud-btn {
    cursor: pointer;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -100%);
    height: 40px;
    line-height: 38px;
    padding: 0 25px;
    outline: none;
    box-sizing: border-box;
    transition: all 0.3s;
    border: 1px solid #23d5ab;
    border-radius: 30px;
    background: transparent;
    color: #23d5ab;
  }

  .cloud-btn:hover {
    color: #fff;
    background: #0c8;
  }
</style>
